package org.jing.core.logger.logback;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import org.jing.core.logger.JingLoggerConfiguration;
import org.jing.core.logger.itf.JingLoggerFactoryItf;
import org.jing.core.logger.itf.JingLoggerItf;
import org.jing.core.logger.itf.JingLoggerLevelItf;
import org.jing.core.logger.sys.SingleLogger;
import org.jing.core.util.StringUtil;
import org.slf4j.Marker;

import java.lang.reflect.Method;
import java.util.List;

/**
 * Description: <br>
 *
 * @author bks <br>
 * @since 2022-11-23 <br>
 */
public class LoggerFactory implements JingLoggerFactoryItf {
    static Method logMethod;

    private LoggerLevel globalLevel;

    @Override public void init(JingLoggerConfiguration config) {
        SingleLogger.log("init Logger.LOGBACK...");
        try {
            logMethod = ch.qos.logback.classic.Logger.class.getDeclaredMethod("filterAndLog_0_Or3Plus", String.class, Marker.class, Level.class, String.class, Object[].class, Throwable.class);
            logMethod.setAccessible(true);
        }
        catch (Throwable t) {
            t.printStackTrace();
        }
    }

    @Override public boolean isEnable() {
        try {
            Class.forName("org.slf4j.LoggerFactory");
        }
        catch (Throwable t) {
            return false;
        }
        return true;
    }

    @Override
    public JingLoggerItf getLogger(String name) {
        return new Logger(name);
    }

    @Override
    public JingLoggerItf getLogger(Class clazz) {
        return new Logger(clazz);
    }

    @Override public boolean isAllEnable() {
        return LoggerLevel.ALL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isTraceEnable() {
        return LoggerLevel.TRACE.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isDebugEnable() {
        return LoggerLevel.DEBUG.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isInfoEnable() {
        return LoggerLevel.INFO.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isWarnEnable() {
        return LoggerLevel.WARN.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isImpEnable() {
        return LoggerLevel.IMP.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isSqlEnable() {
        return LoggerLevel.SQL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isErrorEnable() {
        return LoggerLevel.ERROR.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isFatalEnable() {
        return LoggerLevel.FATAL.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isOffEnable() {
        return LoggerLevel.OFF.isGreaterOrEquals(globalLevel);
    }

    @Override public boolean isLevelEnable(JingLoggerLevelItf level) {
        return level.isGreaterOrEquals(globalLevel);
    }

    @Override public void setGlobalLevel(String levelStr) {
        LoggerLevel level;
        if (StringUtil.isEmpty(levelStr)) {
            level = LoggerLevel.DEFAULT_LEVEL;
        }
        else {
            level = LoggerLevel.valueOf(levelStr.toUpperCase());
        }
        globalLevel = level;
        List<ch.qos.logback.classic.Logger> loggerList = ((LoggerContext) org.slf4j.LoggerFactory.getILoggerFactory()).getLoggerList();
        for (ch.qos.logback.classic.Logger logger : loggerList) {
            logger.setLevel(level.getLevel());
        }
    }
}
